package logs

import (
	"encoding/json"
	"fmt"
	"github.com/rs/zerolog"
	"github.com/rs/zerolog/log"
	"gopkg.in/natefinch/lumberjack.v2"
	"io"
	"os"
	"strings"
	"webGoDemo/model"
)

func WriteAuditLog() {
	log.Info().Msg("审计日记开始！")
	path, _ := os.Getwd()
	dirName := path + "/roll"
	err := os.MkdirAll(dirName, os.ModeDir|os.ModePerm)
	//fileLogger, err := os.OpenFile(dirName+"/audit.logs", os.O_CREATE|os.O_RDWR|os.O_APPEND, os.ModeAppend|os.ModePerm)
	rollLogger := &lumberjack.Logger{
		Filename:   dirName + "/logs.logs",
		MaxSize:    500, // megabytes
		MaxBackups: 3,
		MaxAge:     28,   //days
		Compress:   true, // disabled by default
	}
	if err != nil {
		return
	}
	writers := io.MultiWriter(os.Stdout, rollLogger)
	output := zerolog.ConsoleWriter{Out: writers, TimeFormat: "2006-01-02 15:04:05"}
	// 不输出颜色
	output.NoColor = true
	// 大写level,不加空格
	output.FormatLevel = func(i interface{}) string {
		return "[KAFKA_ACTION_TRAIL_LOG] " + strings.ToUpper(fmt.Sprintf("[%-5s]", i)) + " [outputRecord]"
	}
	output.FormatMessage = func(i interface{}) string {
		return fmt.Sprintf("%s", i)
	}
	//[OP_ACTION_TRAIL_LOG][INFO][outputRecord]
	output.FormatFieldName = func(i interface{}) string {
		return fmt.Sprintf("%s:", i)
	}
	output.FormatFieldValue = func(i interface{}) string {
		return strings.ToUpper(fmt.Sprintf("%s", i))
	}
	auditLogger := zerolog.New(output).With().Timestamp().Logger()
	auditLogger.Output(writers)

	content := &model.User{
		Username: "123",
	}
	logAudit, err := json.Marshal(content)
	if err != nil {
		log.Info().Msg("审计日志转换失败，写入失败！")
	}
	// 写入日志到审计文件中
	auditLogger.Info().Msg(string(logAudit))
	log.Info().Msg("审计日记写入结束！")
}

func NewDefaultConsoleLog() zerolog.Logger {
	output := zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: "2006-01-02 15:04:05"}
	output.FormatLevel = func(i interface{}) string {
		return strings.ToUpper(fmt.Sprintf("[%s]", i))
	}
	output.FormatFieldName = func(i interface{}) string {
		return fmt.Sprintf("[%s", i)
	}
	output.FormatFieldValue = func(i interface{}) string {
		return fmt.Sprintf("%s]", i)
	}
	output.FormatMessage = func(i interface{}) string {
		return fmt.Sprintf("%s", i)
	}
	return zerolog.New(output).With().Timestamp().Logger()
}

type CmqLogger struct {
	output     zerolog.ConsoleWriter
	logger     *lumberjack.Logger
	writer     io.Writer
	MaxSize    int // megabytes
	MaxBackups int
	MaxAge     int  //days
	Compress   bool // disabled by default
}

func (m *CmqLogger) Build() zerolog.Logger {
	m.output.Out = m.writer
	return log.Output(m.output)
}

func (m *CmqLogger) WithConsoleWriter() *CmqLogger {
	m.writer = os.Stdout
	return m
}

// WithTimeFormat /
func (m *CmqLogger) WithTimeFormat(timeFormat string) *CmqLogger {
	m.output.TimeFormat = timeFormat
	return m
}

// WithLevel /
func (m *CmqLogger) WithLevel(level string) *CmqLogger {
	m.output.FormatLevel = func(i interface{}) string {
		return strings.ToUpper(fmt.Sprintf(level, i))
	}
	return m
}

// WithFieldName /
func (m *CmqLogger) WithFieldName(FieldName string) *CmqLogger {

	m.output.FormatFieldName = func(i interface{}) string {
		return fmt.Sprintf(FieldName, i)
	}
	return m
}

// WithFieldValue /
func (m *CmqLogger) WithFieldValue(FieldValue string) *CmqLogger {

	m.output.FormatFieldValue = func(i interface{}) string {
		return fmt.Sprintf(FieldValue, i)
	}
	return m
}

// WithMessage /
func (m *CmqLogger) WithMessage(message string) *CmqLogger {
	m.output.FormatMessage = func(i interface{}) string {
		return fmt.Sprintf(message, i)
	}
	return m
}

// WithColor /
func (m *CmqLogger) WithColor(colorEnable bool) *CmqLogger {
	m.output.NoColor = !colorEnable
	return m
}

// WithFileWriter /
func (m *CmqLogger) WithFileWriter(fileName string, consoleEnable bool) *CmqLogger {
	dir, _ := os.Getwd()
	m.logger = &lumberjack.Logger{
		Filename:   dir + fileName,
		MaxSize:    m.MaxSize, // megabytes
		MaxBackups: m.MaxBackups,
		MaxAge:     m.MaxAge,   //days
		Compress:   m.Compress, // disabled by default
	}
	if consoleEnable {
		m.writer = io.MultiWriter(m.logger, os.Stdout)
	} else {
		m.writer = io.MultiWriter(m.logger)
	}
	return m
}
